package com.ppch.zerocodegenerator.langgraph4j.tools;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ppch.zerocodegenerator.langgraph4j.model.ImageCategoryEnum;
import com.ppch.zerocodegenerator.langgraph4j.model.ImageResource;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Package:ZeroCodeGenerator
 * ClassName:BingImageSearchTool
 *
 * @Author 泡泡茶壶
 * @Create 2025/10/23 10:08
 * @Version 1.0
 * Description:
 * 图片搜索工具（搜索内容图片：从必应网站上进行搜索）
 */
@Slf4j
@Component
public class BingImageSearchTool {

    @Tool("""
            根据关键词从必应网站上搜索内容相关的图片，用于网站内容展示。
            Parameters:
              - searchText: 搜索查询的关键词（例如，"cute cats"）。
              - offset: 结果的偏移量，用于跳过前N张图片，实现分页（默认值：0）。
              - count: 要返回的图片数量（默认值：12，最大值：建议限制）。
             """)
    public List<ImageResource> searchContentImagesFromBing(
            @P("搜索图片关键词") String searchText,
            @P("搜索图片的偏移量，避免同一关键词搜索到重复的图片") int offset,
            @P("搜索图片数量") int count
    ) {
        //1.校验是否传入 offset 参数，如果没有则默认为 0
        if (offset <= 0) {
            offset = 0;
        }
        //2.校验是否传入 count 参数，如果没有则默认为 12
        if (count <= 0) {
            count = 12;
        }
        //3.图片抓取
        String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1&selectedIndex=%s", searchText, offset);
        Document document;
        try {
            //通过URL获取到整个HTML文档
            document = Jsoup.connect(fetchUrl).get();
        } catch (IOException e) {
            log.error("使用Jsoup获取页面文档失败,", e);
            throw new RuntimeException("使用Jsoup获取页面文档失败");
        }
        //解析文档，获取到图片容器
        Elements divContent = document.getElementsByClass("dgControl_list");
        if (ObjectUtil.isNull(divContent)) {
            throw new RuntimeException("获取页面元素失败");
        }

        //获取所有图片容器元素
        Elements imageContainerList = divContent.select("div.imgpt");
        //统计成功添加到集合中的图片数量
        int addSuccessCount = 0;
        //图片信息集合
        List<ImageResource> imageResourceList = new ArrayList<>();

        for (Element container : imageContainerList) {
            //获取图片URL - 从img标签
            Element imageElement = container.selectFirst("img.mimg");
            if (imageElement == null) {
                continue;
            }

            String imageUrl = imageElement.attr("src");
            if (StrUtil.isBlank(imageUrl)) {
                log.error("当前图片URL为空，已跳过");
                continue;
            }

            //处理图片URL，去除URL中 ？ 后面的参数，防止特殊字符导致转义等问题
            int questionMarkIndex = imageUrl.indexOf("?");//问号所在位置的索引下标
            if (questionMarkIndex > -1) { // > -1 说明URL中存在 ？
                imageUrl = imageUrl.substring(0, questionMarkIndex);
            }

            //获取图片描述 - 从同级的div.infopt中的a.inflnk标签的aria-label属性
            String description = "";
            // 找到与当前div.imgpt同级的div.infopt
            Element infoptElement = container.nextElementSibling();
            if (infoptElement != null && infoptElement.hasClass("infopt")) {
                Element linkElement = infoptElement.selectFirst("a.inflnk");
                if (linkElement != null) {
                    description = linkElement.attr("aria-label");
                }
            }

            //如果描述为空，尝试从alt属性获取
            if (StrUtil.isBlank(description)) {
                description = imageElement.attr("alt");
            }
            try {
                //创建图片信息对象
                ImageResource imageResource = new ImageResource();
                imageResource.setCategory(ImageCategoryEnum.CONTENT);
                imageResource.setUrl(imageUrl);
                imageResource.setDescription(StrUtil.isNotBlank(description) ? description : "无描述");
                imageResourceList.add(imageResource);
                addSuccessCount++;
                log.info("图片信息添加到集合成功: URL={}, Desc={}", imageUrl, description);
            } catch (Exception e) {
                log.error("图片信息添加到集合失败", e);
                continue;
            }
            //搜索的图片不能超过设定的数量
            if (addSuccessCount >= count) {
                log.info("图片数量达到设定值，已中断");
                break;
            }
        }
        return imageResourceList;
    }

}